package controllers

import (
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"mishop/entitys"
	"mishop/models"
	"mishop/services"
	"mishop/utils"
	"strconv"
)

type IProduct interface {
	FindByID(ctx *gin.Context)
	All(ctx *gin.Context)
	Show(ctx *gin.Context)
	Update(ctx *gin.Context)
	Store(ctx *gin.Context)
	Delete(ctx *gin.Context)
}

func (p *Product) All(ctx *gin.Context) {
	pageEntity := entitys.PageEntity{}
	err := ctx.ShouldBindWith(&pageEntity, binding.JSON)
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}

	categoryID := 0
	category_id := ctx.Query("category_id")
	if category_id != "" {
		parseInt, err := strconv.Atoi(category_id)
		utils.HandleErrors(err, ctx, 400, 1, "")
		if err != nil {
			return
		}
		categoryID = parseInt
	}
	pages, err := p.service.FindByCategoryID(pageEntity.Page, pageEntity.Rows, uint(categoryID))
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}
	utils.HandleSucess(ctx, 200, 0, "", pages)
}

func (p *Product) Delete(ctx *gin.Context) {
	product_id := ctx.Param("product_id")
	productID, err := strconv.Atoi(product_id)
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}
	err = p.service.Delete(productID)
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}
	utils.HandleSucess(ctx, 200, 0, "删除成功", nil)
}

func (p *Product) Update(ctx *gin.Context) {
	product_id := ctx.Param("product_id")
	productID, err := strconv.Atoi(product_id)
	utils.HandleErrors(err, ctx, 400, 1, "")

	productEntity := models.Product{}
	err = ctx.ShouldBindWith(&productEntity, binding.JSON)
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}
	productEntity.ID = uint(productID)

	product, err := p.service.Update(&productEntity)
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}
	utils.HandleSucess(ctx, 201, 0, "", product)
}

func (p *Product) Show(ctx *gin.Context) {
	product_id := ctx.Param("product_id")
	productID, err := strconv.Atoi(product_id)
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}

	product, err := p.service.FindByID(uint(productID))
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}

	utils.HandleSucess(ctx, 201, 1, "", product)
}

func (p *Product) Store(ctx *gin.Context) {
	productEntity := models.Product{}
	err := ctx.ShouldBindWith(&productEntity, binding.JSON)
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}
	product, err := p.service.Create(&productEntity)
	utils.HandleErrors(err, ctx, 400, 1, "")
	if err != nil {
		return
	}
	utils.HandleSucess(ctx, 201, 1, "", product)
}

type Product struct {
	service services.IProductService
}

func (c *Product) FindByID(ctx *gin.Context) {
	product_id := ctx.Param("product_id")
	productID, err := strconv.Atoi(product_id)
	if err != nil {
		ctx.JSON(400, gin.H{
			"msg": "OK",
		})
		return
	}
	product, err := c.service.FindByID(uint(productID))
	if err != nil {

		ctx.JSON(400, gin.H{
			"msg": "OK" + err.Error(),
		})
		return
	}

	ctx.JSON(200, gin.H{
		"msg":  "OK",
		"data": product,
	})
}

func NewProduct() IProduct {
	service := services.NewProductService(models.NewProduct(models.Db))
	return &Product{service: service}
}
